﻿#nullable disable
using Crux.Core.SQL.Formatter.Core.Util;

namespace Crux.Core.SQL.Formatter.Core;
/// <summary>
/// 
/// </summary>
public class DialectConfig
{
    /// <summary>
    /// 
    /// </summary>
    public readonly List<string> lineCommentTypes;
    /// <summary>
    /// 
    /// </summary>
    public readonly List<string> reservedTopLevelWords;
    /// <summary>
    /// 
    /// </summary>
    public readonly List<string> reservedTopLevelWordsNoIndent;
    /// <summary>
    /// 
    /// </summary>
    public readonly List<string> reservedNewlineWords;
    /// <summary>
    /// 
    /// </summary>
    public readonly List<string> reservedWords;
    /// <summary>
    /// 
    /// </summary>
    public readonly List<string> specialWordChars;
    /// <summary>
    /// 
    /// </summary>
    public readonly List<string> stringTypes;
    /// <summary>
    /// 
    /// </summary>
    public readonly List<string> openParens;
    /// <summary>
    /// 
    /// </summary>
    public readonly List<string> closeParens;
    /// <summary>
    /// 
    /// </summary>
    public readonly List<string> indexedPlaceholderTypes;
    /// <summary>
    /// 
    /// </summary>
    public readonly List<string> namedPlaceholderTypes;
    /// <summary>
    /// 
    /// </summary>
    public readonly List<string> operators;
    private DialectConfig(
        List<string> lineCommentTypes,
        List<string> reservedTopLevelWords,
        List<string> reservedTopLevelWordsNoIndent,
        List<string> reservedNewlineWords,
        List<string> reservedWords,
        List<string> specialWordChars,
        List<string> stringTypes,
        List<string> openParens,
        List<string> closeParens,
        List<string> indexedPlaceholderTypes,
        List<string> namedPlaceholderTypes,
        List<string> operators)
    {
        this.lineCommentTypes = Utils.NullToEmpty(lineCommentTypes);
        this.reservedTopLevelWords = Utils.NullToEmpty(reservedTopLevelWords);
        this.reservedTopLevelWordsNoIndent = Utils.NullToEmpty(reservedTopLevelWordsNoIndent);
        this.reservedNewlineWords = Utils.NullToEmpty(reservedNewlineWords);
        this.reservedWords = Utils.NullToEmpty(reservedWords);
        this.specialWordChars = Utils.NullToEmpty(specialWordChars);
        this.stringTypes = Utils.NullToEmpty(stringTypes);
        this.openParens = Utils.NullToEmpty(openParens);
        this.closeParens = Utils.NullToEmpty(closeParens);
        this.indexedPlaceholderTypes = Utils.NullToEmpty(indexedPlaceholderTypes);
        this.namedPlaceholderTypes = Utils.NullToEmpty(namedPlaceholderTypes);
        this.operators = Utils.NullToEmpty(operators);
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="lineCommentTypes"></param>
    /// <returns></returns>
    public DialectConfig WithLineCommentTypes(List<string> lineCommentTypes)
    {
        return ToBuilder()
            .LineCommentTypes(lineCommentTypes)
            .Build();
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="lineCommentTypes"></param>
    /// <returns></returns>
    public DialectConfig PlusLineCommentTypes(params string[] lineCommentTypes)
    {
        return PlusLineCommentTypes(lineCommentTypes.ToList());
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="lineCommentTypes"></param>
    /// <returns></returns>
    public DialectConfig PlusLineCommentTypes(List<string> lineCommentTypes)
    {
        return ToBuilder()
            .LineCommentTypes(Utils.Concat(this.lineCommentTypes, lineCommentTypes))
            .Build();
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="reservedTopLevelWords"></param>
    /// <returns></returns>
    public DialectConfig WithReservedTopLevelWords(List<string> reservedTopLevelWords)
    {
        return ToBuilder()
            .ReservedTopLevelWords(reservedTopLevelWords)
            .Build();
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="reservedTopLevelWords"></param>
    /// <returns></returns>
    public DialectConfig PlusReservedTopLevelWords(params string[] reservedTopLevelWords)
    {
        return PlusReservedTopLevelWords(reservedTopLevelWords.ToList());
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="reservedTopLevelWords"></param>
    /// <returns></returns>
    public DialectConfig PlusReservedTopLevelWords(List<string> reservedTopLevelWords)
    {
        return ToBuilder()
            .ReservedTopLevelWords(Utils.Concat(this.reservedTopLevelWords, reservedTopLevelWords))
            .Build();
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="reservedNewLineWords"></param>
    /// <returns></returns>
    public DialectConfig WithReservedNewlineWords(List<string> reservedNewLineWords)
    {
        return ToBuilder()
            .ReservedNewlineWords(reservedNewLineWords)
            .Build();
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="reservedNewLineWords"></param>
    /// <returns></returns>
    public DialectConfig PlusReservedNewlineWords(params string[] reservedNewLineWords)
    {
        return PlusReservedNewlineWords(reservedNewLineWords.ToList());
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="reservedNewlineWords"></param>
    /// <returns></returns>
    public DialectConfig PlusReservedNewlineWords(List<string> reservedNewlineWords)
    {
        return ToBuilder()
            .ReservedNewlineWords(Utils.Concat(this.reservedNewlineWords, reservedNewlineWords))
            .Build();
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="reservedTopLevelWordsNoIndent"></param>
    /// <returns></returns>
    public DialectConfig WithReservedTopLevelWordsNoIndent(List<string> reservedTopLevelWordsNoIndent)
    {
        return ToBuilder()
            .ReservedTopLevelWordsNoIndent(reservedTopLevelWordsNoIndent)
            .Build();
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="reservedTopLevelWordsNoIndent"></param>
    /// <returns></returns>
    public DialectConfig PlusReservedTopLevelWordsNoIndent(params string[] reservedTopLevelWordsNoIndent)
    {
        return PlusReservedTopLevelWordsNoIndent(reservedTopLevelWordsNoIndent.ToList());
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="reservedTopLevelWordsNoIndent"></param>
    /// <returns></returns>
    public DialectConfig PlusReservedTopLevelWordsNoIndent(List<string> reservedTopLevelWordsNoIndent)
    {
        return ToBuilder()
            .ReservedTopLevelWordsNoIndent(Utils.Concat(this.reservedTopLevelWordsNoIndent, reservedTopLevelWordsNoIndent))
            .Build();
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="reservedWords"></param>
    /// <returns></returns>
    public DialectConfig WithReservedWords(List<string> reservedWords)
    {
        return ToBuilder()
            .ReservedWords(reservedWords)
            .Build();
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="reservedWords"></param>
    /// <returns></returns>
    public DialectConfig PlusReservedWords(params string[] reservedWords)
    {
        return PlusReservedWords(reservedWords.ToList());
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="reservedWords"></param>
    /// <returns></returns>
    public DialectConfig PlusReservedWords(List<string> reservedWords)
    {
        return ToBuilder()
            .ReservedWords(Utils.Concat(this.reservedWords, reservedWords))
            .Build();
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="specialWordChars"></param>
    /// <returns></returns>
    public DialectConfig WithSpecialWordChars(List<string> specialWordChars)
    {
        return ToBuilder()
            .SpecialWordChars(specialWordChars)
            .Build();
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="specialWordChars"></param>
    /// <returns></returns>
    public DialectConfig PlusSpecialWordChars(params string[] specialWordChars)
    {
        return PlusSpecialWordChars(specialWordChars.ToList());
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="specialWordChars"></param>
    /// <returns></returns>
    public DialectConfig PlusSpecialWordChars(List<string> specialWordChars)
    {
        return ToBuilder()
            .SpecialWordChars(Utils.Concat(this.specialWordChars, specialWordChars))
            .Build();
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="stringTypes"></param>
    /// <returns></returns>
    public DialectConfig WithStringTypes(List<string> stringTypes)
    {
        return ToBuilder()
            .StringTypes(stringTypes)
            .Build();
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="stringTypes"></param>
    /// <returns></returns>
    public DialectConfig PlusStringTypes(params string[] stringTypes)
    {
        return PlusStringTypes(stringTypes.ToList());
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="stringTypes"></param>
    /// <returns></returns>
    public DialectConfig PlusStringTypes(List<string> stringTypes)
    {
        return ToBuilder()
            .StringTypes(Utils.Concat(this.stringTypes, stringTypes))
            .Build();
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="openParens"></param>
    /// <returns></returns>
    public DialectConfig WithOpenParens(List<string> openParens)
    {
        return ToBuilder()
            .OpenParens(openParens)
            .Build();
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="openParens"></param>
    /// <returns></returns>
    public DialectConfig PlusOpenParens(params string[] openParens)
    {
        return PlusOpenParens(openParens.ToList());
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="openParens"></param>
    /// <returns></returns>
    public DialectConfig PlusOpenParens(List<string> openParens)
    {
        return ToBuilder()
            .OpenParens(Utils.Concat(this.openParens, openParens))
            .Build();
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="closeParens"></param>
    /// <returns></returns>
    public DialectConfig WithCloseParens(List<string> closeParens)
    {
        return ToBuilder()
            .CloseParens(closeParens)
            .Build();
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="closeParens"></param>
    /// <returns></returns>
    public DialectConfig PlusCloseParens(params string[] closeParens)
    {
        return PlusCloseParens(closeParens.ToList());
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="closeParens"></param>
    /// <returns></returns>
    public DialectConfig PlusCloseParens(List<string> closeParens)
    {
        return ToBuilder()
            .CloseParens(Utils.Concat(this.closeParens, closeParens))
            .Build();
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="indexedPlaceholderTypes"></param>
    /// <returns></returns>
    public DialectConfig WithIndexedPlaceholderTypes(List<string> indexedPlaceholderTypes)
    {
        return ToBuilder()
            .IndexedPlaceholderTypes(indexedPlaceholderTypes)
            .Build();
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="indexedPlaceholderTypes"></param>
    /// <returns></returns>
    public DialectConfig PlusIndexedPlaceholderTypes(params string[] indexedPlaceholderTypes)
    {
        return PlusIndexedPlaceholderTypes(indexedPlaceholderTypes.ToList());
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="indexedPlaceholderTypes"></param>
    /// <returns></returns>
    public DialectConfig PlusIndexedPlaceholderTypes(List<string> indexedPlaceholderTypes)
    {
        return ToBuilder()
            .IndexedPlaceholderTypes(Utils.Concat(this.indexedPlaceholderTypes, indexedPlaceholderTypes))
            .Build();
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="namedPlaceholderTypes"></param>
    /// <returns></returns>
    public DialectConfig WithNamedPlaceholderTypes(List<string> namedPlaceholderTypes)
    {
        return ToBuilder()
            .NamedPlaceholderTypes(namedPlaceholderTypes)
            .Build();
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="namedPlaceholderTypes"></param>
    /// <returns></returns>
    public DialectConfig PlusNamedPlaceholderTypes(params string[] namedPlaceholderTypes)
    {
        return PlusNamedPlaceholderTypes(namedPlaceholderTypes.ToList());
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="namedPlaceholderTypes"></param>
    /// <returns></returns>
    public DialectConfig PlusNamedPlaceholderTypes(List<string> namedPlaceholderTypes)
    {
        return ToBuilder()
            .NamedPlaceholderTypes(Utils.Concat(this.namedPlaceholderTypes, namedPlaceholderTypes))
            .Build();
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="operators"></param>
    /// <returns></returns>
    public DialectConfig WithOperators(List<string> operators)
    {
        return ToBuilder()
            .Operators(operators)
            .Build();
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="operators"></param>
    /// <returns></returns>
    public DialectConfig PlusOperators(params string[] operators)
    {
        return PlusOperators(operators.ToList());
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="operators"></param>
    /// <returns></returns>
    public DialectConfig PlusOperators(List<string> operators)
    {
        return ToBuilder()
            .Operators(Utils.Concat(this.operators, operators))
            .Build();
    }
    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public DialectConfigBuilder ToBuilder()
    {
        return Builder()
            .LineCommentTypes(lineCommentTypes)
            .ReservedTopLevelWords(reservedTopLevelWords)
            .ReservedTopLevelWordsNoIndent(reservedTopLevelWordsNoIndent)
            .ReservedNewlineWords(reservedNewlineWords)
            .ReservedWords(reservedWords)
            .SpecialWordChars(specialWordChars)
            .StringTypes(stringTypes)
            .OpenParens(openParens)
            .CloseParens(closeParens)
            .IndexedPlaceholderTypes(indexedPlaceholderTypes)
            .NamedPlaceholderTypes(namedPlaceholderTypes)
            .Operators(operators);
    }
    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    public static DialectConfigBuilder Builder()
    {
        return new DialectConfigBuilder();
    }
    /// <summary>
    /// 
    /// </summary>
    public class DialectConfigBuilder
    {
        /// <summary>
        /// 
        /// </summary>
        private List<string> lineCommentTypes;
        /// <summary>
        /// 
        /// </summary>
        private List<string> reservedTopLevelWords;
        /// <summary>
        /// 
        /// </summary>
        private List<string> reservedTopLevelWordsNoIndent;
        /// <summary>
        /// 
        /// </summary>
        private List<string> reservedNewlineWords;
        /// <summary>
        /// 
        /// </summary>
        private List<string> reservedWords;
        /// <summary>
        /// 
        /// </summary>
        private List<string> specialWordChars;
        /// <summary>
        /// 
        /// </summary>
        private List<string> stringTypes;
        /// <summary>
        /// 
        /// </summary>
        private List<string> openParens;
        /// <summary>
        /// 
        /// </summary>
        private List<string> closeParens;
        /// <summary>
        /// 
        /// </summary>
        private List<string> indexedPlaceholderTypes;
        /// <summary>
        /// 
        /// </summary>
        private List<string> namedPlaceholderTypes;
        /// <summary>
        /// 
        /// </summary>
        private List<string> operators;

        /// <summary>
        /// 
        /// </summary>
        public DialectConfigBuilder LineCommentTypes(List<string> lineCommentTypes)
        {
            this.lineCommentTypes = lineCommentTypes;
            return this;
        }

        /// <summary>
        /// 
        /// </summary>
        public DialectConfigBuilder ReservedTopLevelWords(List<string> reservedTopLevelWords)
        {
            this.reservedTopLevelWords = reservedTopLevelWords;
            return this;
        }

        /// <summary>
        /// 
        /// </summary>
        public DialectConfigBuilder ReservedTopLevelWordsNoIndent(List<string> reservedTopLevelWordsNoIndent)
        {
            this.reservedTopLevelWordsNoIndent = reservedTopLevelWordsNoIndent;
            return this;
        }

        /// <summary>
        /// 
        /// </summary>
        public DialectConfigBuilder ReservedNewlineWords(List<string> reservedNewlineWords)
        {
            this.reservedNewlineWords = reservedNewlineWords;
            return this;
        }

        /// <summary>
        /// 
        /// </summary>
        public DialectConfigBuilder ReservedWords(List<string> reservedWords)
        {
            this.reservedWords = reservedWords;
            return this;
        }
        /// <summary>
        /// 
        /// </summary>
        public DialectConfigBuilder SpecialWordChars(List<string> specialWordChars)
        {
            this.specialWordChars = specialWordChars;
            return this;
        }
        /// <summary>
        /// 
        /// </summary>

        public DialectConfigBuilder StringTypes(List<string> stringTypes)
        {
            this.stringTypes = stringTypes;
            return this;
        }

        /// <summary>
        /// 
        /// </summary>
        public DialectConfigBuilder OpenParens(List<string> openParens)
        {
            this.openParens = openParens;
            return this;
        }

        /// <summary>
        /// 
        /// </summary>
        public DialectConfigBuilder CloseParens(List<string> closeParens)
        {
            this.closeParens = closeParens;
            return this;
        }

        /// <summary>
        /// 
        /// </summary>
        public DialectConfigBuilder IndexedPlaceholderTypes(List<string> indexedPlaceholderTypes)
        {
            this.indexedPlaceholderTypes = indexedPlaceholderTypes;
            return this;
        }

        /// <summary>
        /// 
        /// </summary>
        public DialectConfigBuilder NamedPlaceholderTypes(List<string> namedPlaceholderTypes)
        {
            this.namedPlaceholderTypes = namedPlaceholderTypes;
            return this;
        }

        /// <summary>
        /// 
        /// </summary>
        public DialectConfigBuilder Operators(List<string> operators)
        {
            this.operators = operators;
            return this;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns> <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public DialectConfig Build()
        {
            return new DialectConfig(
                lineCommentTypes,
                reservedTopLevelWords,
                reservedTopLevelWordsNoIndent,
                reservedNewlineWords,
                reservedWords,
                specialWordChars,
                stringTypes,
                openParens,
                closeParens,
                indexedPlaceholderTypes,
                namedPlaceholderTypes,
                operators);
        }
    }
}
